package com.smart.manager.task;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.smart.common.annotation.TaskBean;
import com.smart.common.annotation.TaskMethod;
import com.smart.common.entities.core.BaseLongModel;
import com.smart.common.entities.domain.TaskResult;
import com.smart.manager.member.entities.enums.*;
import com.smart.manager.member.entities.models.MemberMaterialPig;
import com.smart.manager.member.entities.models.MemberMaterialPigPlan;
import com.smart.manager.member.entities.models.MemberMaterialSort;
import com.smart.manager.member.entities.models.MemberProfileAccount;
import com.smart.manager.member.entities.models.query.QMemberMaterialPig;
import com.smart.manager.member.entities.models.query.QMemberMaterialPigPlan;
import com.smart.manager.member.entities.models.query.QMemberMaterialSort;
import com.smart.manager.member.entities.views.MemberPigView;
import com.smart.manager.member.repository.MemberAccountRepository;
import com.smart.manager.member.repository.MemberMaterialPigPlanRepository;
import com.smart.manager.member.repository.MemberMaterialPigUseRepository;
import com.smart.manager.pop.entities.enums.BillKind;
import com.smart.manager.pop.repository.DisInviterRepository;
import com.smart.manager.product.entities.enums.PigStatus;
import com.smart.manager.product.entities.models.PropsCombo;
import com.smart.manager.product.entities.models.query.QPropsCombo;
import com.smart.manager.product.entities.views.BasicPigstyView;
import com.smart.manager.product.entities.views.PropsComboView;
import com.smart.manager.product.entities.views.PropsProfileView;
import com.smart.manager.product.entities.views.PropsSnacksView;
import com.smart.manager.product.entities.views.query.QBasicPigstyView;
import com.smart.manager.product.entities.views.query.QPropsComboView;
import com.smart.manager.product.entities.views.query.QPropsProfileView;
import com.smart.manager.product.entities.views.query.QPropsSnacksView;
import com.smart.manager.work.entities.assembler.AffixList;
import com.smart.manager.work.entities.assembler.WorkOrder;
import com.smart.manager.work.entities.enums.PigOrderKind;
import com.smart.manager.work.entities.enums.PigOrderStatus;
import com.smart.manager.work.entities.models.PigOrderFoods;
import com.smart.service.remind.RemindService;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 生成自动喂食工单
 *
 * @author leo
 * @date 2023/10/10
 */
@Log4j2
@Component
@TaskBean
@RequiredArgsConstructor
public class AutoFeedingTaskV1 {

    private final MemberAccountRepository memberAccountRepository;
    private final MemberMaterialPigPlanRepository memberMaterialPigPlanRepository;
    private final MemberMaterialPigUseRepository memberMaterialPigUseRepository;
    private final RemindService remindService;
    private final DisInviterRepository disInviterRepository;

    @TaskMethod(title = "定时喂养(按圈喂养)")
    public synchronized TaskResult feedRegularlyEarly(String time) {
        try {
//            List<AffixList> affixLists1 = setCs();
            //测试零食
            PigPlanTime planTime = time.equals(PigPlanTime.L1.getValue()) ? PigPlanTime.L1 : time.equals(PigPlanTime.L2.getValue()) ? PigPlanTime.L2 : PigPlanTime.L3;
            log.warn("开始执行喂食(转换)  {}", planTime);
            LocalDate dateTime = LocalDate.now();
            List<PropsProfileView> profileViews = new QPropsProfileView().findList();
            List<BasicPigstyView> pigstyViews = new QBasicPigstyView().findList();

            List<PigOrderFoods> pigOrderFoodsList = new ArrayList<>();

            pigstyViews.forEach(pigStys -> {
                String pigSty = pigStys.getCode();
                List<PropsComboView> list = new QPropsComboView().isPack.eq(false).isOrganic.eq(pigStys.getIsOrganic()).findList();
                List<MemberMaterialPig> pigs = new QMemberMaterialPig().pigsty.code.eq(pigSty).status.eq(PigStatus.NORMAL).findList();
                //生成工单号
                String order = String.format("GD%s%s", DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN), RandomUtil.randomNumbers(3));
                List<MemberMaterialPigPlan> pigPlans = new ArrayList<>();

                for (MemberMaterialPig pig : pigs) {
                    MemberMaterialPigPlan newPigsPlan = null;
                    Optional<MemberMaterialPigPlan> pigPlan = seekPigPlan(pig.getId(), dateTime, planTime);
                    if (pigPlan.isEmpty()) {
                        //进行购买
                        Optional<PropsCombo> combo = new QPropsCombo().isPack.eq(true).setMaxRows(1).findOneOrEmpty();
                        if (combo.isEmpty()) {
                            log.warn("{}_自动喂食失败 没有低保套餐 猪仔: {}", DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"), pig.getCode());
                            continue;
                        }
                        //扣款
                        MemberProfileAccount account = memberAccountRepository.getAccount(pig.getMember().getId());
                        if (account.getCoinBalance() > combo.get().getPrice()) {
                            memberAccountRepository.saveEvent(pig.getMember().getId(), CoinAccountEvent.AUTOMATIC, combo.get().getPrice(), "系统自动喂养:" + pig.getName());
                            log.warn("扣取玩家账户");
                        } else if (pig.getReserveFund() > combo.get().getPrice()) {
                            //如果不够 则扣取备用金
                            pig.setReserveFund(pig.getReserveFund() - combo.get().getPrice()).update();
                            //
                            remindService.sendAutoWeishi(pig.getMember().getId(), pig);

                            log.warn("扣取备用金");
                        } else {
                            //一天只发一次
                            if (planTime.equals(PigPlanTime.L1)) {
                                remindService.sendAutoOut(pig.getMember().getId(), pig);
                            }
                            pig.setReserveFund(pig.getReserveFund() - combo.get().getPrice()).update();
                            log.error("{}_自动喂食失败 猪仔备用金不足: {}", DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"), pig.getCode());
                        }
                        //生成一天食物
                        memberMaterialPigPlanRepository.add(pig, combo.get(), dateTime);
                        Optional<MemberMaterialPigPlan> newPigPlan = seekPigPlan(pig.getId(), dateTime, planTime);
                        if (newPigPlan.isPresent()) {
                            newPigsPlan = newPigPlan.get();
                        } else {
                            log.error("{}_自动喂食失败 猪仔: {}", DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"), pig.getCode());
                            continue;
                        }
                    } else {
                        newPigsPlan = pigPlan.get();
                    }
                    if (newPigsPlan.getCombo().getIsPack()) {
                        List<PropsComboView> comboViews = list.stream()
                                .filter(x -> x.getMaxLevel() >= pig.getPigLevel().getDay() && x.getMinLevel() <= pig.getPigLevel().getDay()).collect(Collectors.toList());

                        log.warn("转换套餐: 是否是有机 {}",newPigsPlan.getCombo().getIsOrganic());
                        log.warn("转换套餐: 可用数据有 {}",list.stream().map(PropsComboView::getCode).collect(Collectors.toList()));
                        log.warn("转换套餐: 转换前{}",newPigsPlan.getCombo().getName());
                        log.warn("转换套餐: 转换后{}",comboViews.get(0).getName());
                        if (CollUtil.isEmpty(comboViews)) {
                            log.warn("未找到对应套餐！");
                            continue;
                        }
                        newPigsPlan.setCombo(comboViews.get(0));
                        log.warn("最终套餐 : code:{},{},{}", newPigsPlan.getCombo().getCode(), newPigsPlan.getCombo().getMinLevel(), newPigsPlan.getCombo().getMaxLevel());
                    }
                    //计算喂食套餐
                    disInviterRepository.buyPig(pig.getMember().getPhoneNumber(), BillKind.EATING, BigDecimal.valueOf(newPigsPlan.getCombo().getPrice()));

                    newPigsPlan.setStatus(PigPlanStatus.L1).update();
                    memberMaterialPigUseRepository.add(pig.getMember().getId(), pig.getId(), PigUseKind.L1, PigUseState.DSX, 1, order);
                    pigPlans.add(newPigsPlan);
                }
                log.warn("生成的猪有{}", pigs.stream().map(MemberMaterialPig::getCode).collect(Collectors.toList()));
                log.warn("pigPlans = {}", pigPlans);
                if (pigPlans.size()>0&&pigs.size()>0) {
                    List<Long> pigIdList = pigs.stream().map(BaseLongModel::getId).collect(Collectors.toList());
                    List<String> pigCodeList = pigs.stream().map(MemberMaterialPig::getCode).collect(Collectors.toList());

                    //生成订单 放入零食排队
                    List<MemberMaterialSort> sorts = new QMemberMaterialSort().pigId.id.in(pigIdList).status.eq(SortState.DSX).findList();
                    List<AffixList> affixLists = new ArrayList<>();
                    if (CollUtil.isNotEmpty(sorts)) {
                        affixLists = sorts.stream().map(x -> new AffixList().setCode(x.getSnacks()).setName(x.getSnacks().getName()).setAmount(x.getNumber()).setImage(x.getSnacks().getIcon()))
                                .collect(Collectors.toList());
                        log.warn("排队的零食有  {}", affixLists);
                        List<MemberMaterialSort> collect = sorts.stream().map(x -> x.setStatus(SortState.YSX)).collect(Collectors.toList());
                        DB.updateAll(collect);
                    }
                    MemberMaterialPigPlan pigPlan = pigPlans.get(0);
                    List<String> meat = pigPlan.getCombo().getMeat();
                    List<PropsProfileView> collect = profileViews.stream().filter(x -> meat.contains(x.getCode())).collect(Collectors.toList());
                    WorkOrder.FeedBody feedBody = new WorkOrder.FeedBody().setFoods(collect).setCombo(pigPlan.getCombo()).setAffix(affixLists);
                    //生成工单
                    PigOrderFoods pigOrderFoods = new PigOrderFoods()
                            .setPigsty(new BasicPigstyView().setCode(pigSty))
                            .setPigCodeList(pigCodeList)
                            .setStaff(pigs.get(0).getStaff())
                            .setCode(order)
                            .setStatus(PigOrderStatus.PROGRESS)
                            .setKind(PigOrderKind.L3)
                            .setContent(feedBody);
                    pigOrderFoodsList.add(pigOrderFoods);
                }
            });

            DB.insertAll(pigOrderFoodsList);
            return new TaskResult(true, "一共" + pigstyViews.size() + "个圈,生成了"+pigOrderFoodsList.size()+"条工单");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new TaskResult(true, "");
    }




    public List<AffixList>  setCs(){
        List<PropsSnacksView> list = new QPropsSnacksView().findList();
        return list.stream().map(x -> new AffixList().setCode(x).setName(x.getName()).setAmount(5).setImage(x.getIcon())).collect(Collectors.toList());
    }

    /**
     * 查询计划
     *
     * @param id       猪仔id
     * @param dateTime 投喂日期
     * @param time     投喂时间段
     * @return {@link MemberMaterialPigPlan}
     */
    private Optional<MemberMaterialPigPlan> seekPigPlan(Long id, LocalDate dateTime, PigPlanTime time) {
        log.warn("id == {} 时间是 = {} , time =  {}", id, dateTime, time);
        List<MemberMaterialPigPlan> list = new QMemberMaterialPigPlan().status.eq(PigPlanStatus.L2).pigId.eq(new MemberPigView().setId(id)).eatDate.eq(dateTime).eatTime.eq(time).findList();
        log.warn("查询数据 === {} 长度 = {}", list, list.size());
        return new QMemberMaterialPigPlan().status.eq(PigPlanStatus.L2).pigId.eq(new MemberPigView().setId(id)).eatDate.eq(dateTime).eatTime.eq(time).setMaxRows(1).findOneOrEmpty();
    }
}
